#include "animal.hpp"
#include <arpa/inet.h>
#include <atomic>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <dlfcn.h>
#include <iostream>
#include <mutex>
#include <sys/socket.h>
#include <thread>
#include <unistd.h>
#include <unordered_map>

using namespace std;

atomic_bool server_running{true}; // 全局运行状态标志
unordered_map<string, AnimalPtr> zoo;
mutex zoo_mutex;

void handle_connection(int sock) {
  char buffer[1024] = {0};

  // 修复1：确保消息完整性和字符串终止
  ssize_t bytes_read = read(sock, buffer, sizeof(buffer) - 1);
  if (bytes_read <= 0) {
    cerr << "Connection closed or read error" << endl;
    close(sock);
    return;
  }
  buffer[bytes_read] = '\0'; // 强制终止字符串

  // 调试输出原始消息
  cout << "[DEBUG] Raw message: |" << buffer << "|" << endl;

  // 解析命令
  char *cmd = strtok(buffer, " \t\n"); // 允许空格/tab/换行分隔
  if (!cmd) {
    cerr << "Empty command" << endl;
    close(sock);
    return;
  }

  string action(cmd);

  // 处理启动命令
  if (action == "start") {
    char *type = strtok(nullptr, " \t\n");
    char *name = strtok(nullptr, " \t\n");

    // 修复2：严格参数检查
    if (!type || !name) {
      cerr << "Invalid start format. Usage: start <type> <name>" << endl;
      close(sock);
      return;
    }

    cout << "[DEBUG] Parsed type: " << type << ", name: " << name << endl;

    string key = string(type) + "_" + name;
    string so_path = string("../lib/") + type + ".so"; // 修复3：调整库路径

    // 调试库路径
    cout << "[DEBUG] Loading library: " << so_path << endl;

    void *handle = dlopen(so_path.c_str(), RTLD_LAZY);
    if (!handle) {
      cerr << "DL Error: " << dlerror()
           << " (Current working directory: " << getcwd(nullptr, 0) << ")"
           << endl;
      close(sock);
      return;
    }

    // 修复4：明确函数指针类型
    using CreateFunc = Animal *(*)(const char *);
    using DestroyFunc = void (*)(Animal *);

    auto create = (CreateFunc)dlsym(handle, "create_animal");
    auto destroy = (DestroyFunc)dlsym(handle, "destroy_animal");

    if (!create || !destroy) {
      cerr << "Symbol Error: " << dlerror() << endl;
      dlclose(handle);
      close(sock);
      return;
    }

    {
      lock_guard<mutex> lock(zoo_mutex);
      if (!zoo.count(key)) {
        // 修复5：直接构造避免operator[]的默认构造
        zoo.emplace(key, AnimalPtr(create(name), destroy));
        cout << "✅ Started " << key << endl;
      } else {
        cout << "⚠️ " << key << " already exists" << endl;
      }
    }

    // 保持句柄打开以保证销毁函数有效
  }
  // 处理停止命令
  else if (action == "stop") {
    lock_guard<mutex> lock(zoo_mutex);
    char *key;
    while ((key = strtok(nullptr, " \t\n")) != nullptr) {
      if (zoo.erase(key)) {
        cout << "⛔ Stopped " << key << endl;
      } else {
        cerr << "🚫 Not found: " << key << endl;
      }
    }
  } else {
    cerr << "Unknown action: " << action << endl;
  }

  close(sock);
}

void timer_thread() {
  const auto kSoundInterval = chrono::seconds(3);

  while (true) {
    this_thread::sleep_for(kSoundInterval);

    lock_guard<mutex> lock(zoo_mutex);
    if (zoo.empty()) {
      cout << "[TIMER] Zoo is empty" << endl;
      continue;
    }

    // 随机选择算法优化
    auto it = zoo.begin();
    advance(it, rand() % zoo.size());

    cout << "🔊 Active " << it->first << " says: ";
    it->second->sound();
  }
}

void listener_thread(int server_fd) {
  cout << "👂 Listener thread started on fd: " << server_fd << endl;

  while (server_running) { // 受控运行循环
    sockaddr_in client_addr;
    socklen_t addr_len = sizeof(client_addr);

    int client_sock = accept(server_fd, (sockaddr *)&client_addr, &addr_len);
    if (client_sock < 0) {
      if (server_running) { // 过滤正常关闭时的错误
        cerr << "⚠️ Accept error: " << strerror(errno) << endl;
      }
      continue;
    }

    // 获取客户端IP信息
    char client_ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip));
    cout << "🌍 Connection from " << client_ip << ":"
         << ntohs(client_addr.sin_port) << endl;

    thread([client_sock] {
      handle_connection(client_sock);
      close(client_sock); // 确保关闭客户端socket
    }).detach();
  }

  cout << "🛑 Listener thread stopping" << endl;
}

int main() {
  srand(time(nullptr));

  // 网络初始化
  int server_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (server_fd < 0) {
    cerr << "❌ Socket creation failed: " << strerror(errno) << endl;
    return EXIT_FAILURE;
  }

  // 端口复用
  int opt = 1;
  setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

  sockaddr_in address;
  address.sin_family = AF_INET;
  address.sin_addr.s_addr = INADDR_ANY;
  address.sin_port = htons(8080);

  if (bind(server_fd, (sockaddr *)&address, sizeof(address)) < 0) {
    cerr << "❌ Bind failed: " << strerror(errno) << endl;
    close(server_fd);
    return EXIT_FAILURE;
  }

  if (listen(server_fd, 10) < 0) {
    cerr << "❌ Listen failed: " << strerror(errno) << endl;
    close(server_fd);
    return EXIT_FAILURE;
  }

  // 显示当前工作目录
  cout << "🛠️  Current working directory: " << getcwd(nullptr, 0) << endl;
  cout << "🐾 Zoo server starting on port 8080" << endl;

  // 定时器线程
  thread timer([] {
    cout << "⏰ Timer thread started" << endl;
    timer_thread();
  });
  timer.detach();

  thread listener([server_fd] { listener_thread(server_fd); });
  listener.detach();

  // 主线程等待终止信号
  cout << "🚀 Server running. Press Ctrl+C to exit" << endl;
  while (server_running) {
    this_thread::sleep_for(chrono::seconds(1));
  }
  cout << "🛑 Server shutting down..." << endl;
  // 理论上不可达的清理代码
  close(server_fd);
  return EXIT_SUCCESS;
}